import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;

import com.utilities.IO.FileUtilities;
import com.utilities.dataStructures.Range;

public class PrimeFinder {
	
	public static void main(String[] args) throws Exception
	{
		String inputcontigsfile = "C:/Users/bansalp/home/Desktop/UZH/newCosmid/run1run2/all/contigs.fna";
		String outputSegmentFile = "C:/Users/bansalp/home/Desktop/UZH/newCosmid/run1run2/all/segment.fna";
		PrimeFinder finder = new PrimeFinder();
		finder.find(inputcontigsfile,outputSegmentFile);
	}

	public ArrayList<Range> find(String inputcontigsfile, String outputSegmentFile) throws Exception
	{
		ArrayList<Range> contigs = readFromFile(inputcontigsfile);
		ArrayList<Range> result = new ArrayList<Range>();
		Range startContig = findStartContig(contigs, 0);
		int start = contigs.get(0).getLowerLimit();
		int end = start + 1600;
		while(end <= 66000)
		{
			Range endContig = findEndContig(contigs, end);
			if (endContig == null)
			{
				int newend = end + 200;
				endContig = findEndContig(contigs, newend);
				if (endContig != null)
				{
					end = newend;
				}
			}
			if (endContig != null)
			{
				Range r = new Range(start, end, startContig.getMetadata() + ":" + endContig.getMetadata());
				result.add(r);
				System.out.println(r.getLowerLimit() + " " + r.getUpperLimit()) ;
				start = end - 70;
				end = start + 1600;
				startContig = endContig;
			}
			else
			{
//				endContig = findNearestLowest(contigs,end);
				Range r = new Range(start, startContig.getUpperLimit(), startContig.getMetadata() + ":" 
						+ startContig.getMetadata());
				result.add(r);
				System.out.println(r.getLowerLimit() + " " + r.getUpperLimit()) ;
				startContig = findStartContig(contigs,end); 
				if (startContig == null)
				{
					break;
				}
				start = startContig.getLowerLimit();
				end = start + 1600; 
			}
		}
		FileUtilities.WriteToFile(result, outputSegmentFile);
		return result;
	}

//	private Range findNearestLowest(ArrayList<Range> contigs, int end) 
//	{
//		Range previousRange = null;
//		for(Range range : contigs)
//		{
//			if (previousRange == null)
//			{
//				previousRange = range;
//			}
//			else
//			{
//				if (end > previousRange.getUpperLimit() && end < range.getLowerLimit())
//				{
//					
//				}
//			}
//			int _start = range.getLowerLimit();
//			int _end = range.getUpperLimit();
//			if (end <)
//		}
//		return null;
//	}

	private Range findStartContig(ArrayList<Range> contigs, int end) 
	{
		for(Range contig : contigs)
		{
			if (end < contig.getLowerLimit() && contig.getActualLength() >=70)
			{
				return contig;
			}
		}
		return null;
	}

	private Range findEndContig(ArrayList<Range> contigs, int end) {
		Range contig = null;
		for(Range _contig : contigs)
		{
			if (_contig.getLowerLimit() < end && end < (_contig.getLowerLimit() + _contig.getActualLength()))
			{
				if (end - _contig.getLowerLimit() >= 70)
				{
					// read the contig string from the file and find if it ends with G/C
					contig = _contig;
					break;
				}
			}
			else if (end < _contig.getLowerLimit())
			{
				break;
			}
		}
		return contig;
	}

	public ArrayList<Range> readFromFile(String file) throws Exception
	{
		ArrayList<Range> arrayList = new ArrayList<Range>();
		BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
		String readLine = bufferedReader.readLine();
		while(readLine != null)
		{
			if (readLine.startsWith(">"))
			{
				String[] params = readLine.trim().replaceAll("( )+", " ").split(" ");
				int start = Integer.parseInt(params[2].split("[.][.]")[0]);
				int end = Integer.parseInt(params[2].split("[.][.]")[1]);
				int length = Integer.parseInt(params[3].split("=")[1]);
				String name = params[0].substring(1);
				Range range = new Range(start,end,name);
				range.setActualLength((double)length);
				arrayList.add(range);
			}
			readLine = bufferedReader.readLine();
		}
		return arrayList;
	}
}
